package com.ocm.tourism.web;

import java.awt.Dimension;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.ocm.tourism.core.domain.Catalogues;
import com.ocm.tourism.core.domain.FileInfo;
import com.ocm.tourism.core.domain.SightSeeing;
import com.ocm.tourism.core.service.CataloguesService;
import com.ocm.tourism.file.MimeTypeSupport;
import com.ocm.tourism.file.SimpleImageInfo;
import com.ocm.tourism.web.util.FileInfoUtil;

@RequestMapping("/sightseeing")
@Controller
public class SightSeeingController {

   @Autowired
   CataloguesService cataloguesService;

   @Autowired
   FileInfoUtil fileInfoUtil;

   @RequestMapping(value = "/{attractionType}/{attractionMenu}", method=RequestMethod.GET)
   public String viewSightSeeing(@PathVariable("attractionType") String attractionType,@PathVariable("attractionMenu") String attractionMenu, Model uiModel) {
      uiModel.addAttribute("attractionType", attractionType);
      uiModel.addAttribute("attractionMenu", attractionMenu);
      String cateloguesType = createCateloguesType(attractionType, attractionMenu);
      Catalogues catalogues = this.cataloguesService.findCatalogues(cateloguesType);
      populateEditForm(uiModel, catalogues);
      return "sightseeing/list";
   }

   @RequestMapping(value = "/detail/{sightseeingId}", method=RequestMethod.GET)
   public String viewSightSeeingDetail(@PathVariable("sightseeingId") Long sightseeingId, Model uiModel) {
      SightSeeing sightSeeing = this.cataloguesService.findSightSeeing(sightseeingId);
      populateEditForm(uiModel, sightSeeing);
      return "sightseeing/detail";
   }
   
   @RequestMapping(value = "/{attractionType}/{attractionMenu}/{sightseeingId}", method=RequestMethod.GET)
   public String viewSightSeeing(@PathVariable("attractionType") String attractionType,@PathVariable("attractionMenu") String attractionMenu,@PathVariable("sightseeingId") Long sightseeingId, Model uiModel) {
      uiModel.addAttribute("attractionType", attractionType);
      uiModel.addAttribute("attractionMenu", attractionMenu);
      SightSeeing sightSeeing = this.cataloguesService.findSightSeeing(sightseeingId);
      uiModel.addAttribute("itemId", sightSeeing.getId());
      populateEditForm(uiModel, sightSeeing);
      return "sightseeing/show";
   }

   @RequestMapping(value = "/{attractionType}/{attractionMenu}/{sightseeingId}/update", method=RequestMethod.GET)
   public String updateSightSeeingForm(@PathVariable("attractionType") String attractionType,@PathVariable("attractionMenu") String attractionMenu,@PathVariable("sightseeingId") Long sightseeingId, Model uiModel) {
      uiModel.addAttribute("attractionType", attractionType);
      uiModel.addAttribute("attractionMenu", attractionMenu);
      SightSeeing sightSeeing = this.cataloguesService.findSightSeeing(sightseeingId);
      uiModel.addAttribute("itemId", sightSeeing.getId());
      populateEditForm(uiModel, sightSeeing);
      return "sightseeing/update";
   }

   @RequestMapping(value = "/{attractionType}/{attractionMenu}/create", method=RequestMethod.GET)
   public String createSightSeeingForm(@PathVariable("attractionType") String attractionType,@PathVariable("attractionMenu") String attractionMenu, Model uiModel) {
      uiModel.addAttribute("attractionType", attractionType);
      uiModel.addAttribute("attractionMenu", attractionMenu);
      SightSeeing sightSeeing = new SightSeeing();
      populateEditForm(uiModel, sightSeeing);
      return "sightseeing/create";
   }

   @RequestMapping(value = "/{attractionType}/{attractionMenu}", method=RequestMethod.POST)
   public String createSightSeeing(@PathVariable("attractionType") String attractionType,@PathVariable("attractionMenu") String attractionMenu, @Valid SightSeeing sightSeeing, @RequestParam("fileData")CommonsMultipartFile commonsMultipartFile, Model uiModel, BindingResult bindingResult, HttpServletRequest httpServletRequest) throws Exception {
      uiModel.addAttribute("attractionType", attractionType);
      uiModel.addAttribute("attractionMenu", attractionMenu);
      if (bindingResult.hasErrors()){
         return "sightseeing/create";
      }
      if (commonsMultipartFile.getSize() > 0){
         String uploadDir = httpServletRequest.getSession().getServletContext().getInitParameter("uploadDir");
         String folderPath = fileInfoUtil.createContainer(uploadDir);
         FileInfo fileInfo = fileInfoUtil.writeFile(commonsMultipartFile, uploadDir, folderPath);
         sightSeeing.setAvatar(fileInfo);
      }
      String cateloguesType = createCateloguesType(attractionType, attractionMenu);
      Catalogues catalogues = this.cataloguesService.findCatalogues(cateloguesType);
      if (catalogues == null){
         catalogues = new Catalogues();
         catalogues.setCataloguesType(cateloguesType);
         catalogues.setName(cateloguesType);
      }
      catalogues.addSightSeeing(sightSeeing);
      this.cataloguesService.saveCatalogues(catalogues);
      return "redirect:/sightseeing/"+attractionType+"/"+attractionMenu;
   }

   @RequestMapping(value = "/{attractionType}/{attractionMenu}/{sightseeingId}", method=RequestMethod.DELETE)
   public String deleteSightSeeing(@PathVariable("attractionType") String attractionType,@PathVariable("attractionMenu") String attractionMenu, @PathVariable("sightseeingId") Long sightseeingId, Model uiModel) {
      uiModel.addAttribute("attractionType", attractionType);
      uiModel.addAttribute("attractionMenu", attractionMenu);
      String cateloguesType = createCateloguesType(attractionType, attractionMenu);
      Catalogues catalogues = this.cataloguesService.findCatalogues(cateloguesType);
      if (catalogues != null){
         catalogues.removeSightSeeing(sightseeingId);
         this.cataloguesService.saveCatalogues(catalogues);
      }
      return "redirect:/sightseeing/"+attractionType+"/"+attractionMenu;
   }

   private String createCateloguesType(String attractionType, String attractionMenu){
      return attractionType+"_"+attractionMenu;
   }

   private void populateEditForm(Model uiModel, Catalogues catalogues) {
      catalogues = catalogues == null ? new Catalogues() : catalogues;
      List<SightSeeing> sightSeeings = catalogues.getSightseeings();
      uiModel.addAttribute("sightseeeings", sightSeeings);
  }
   
   private void populateEditForm(Model uiModel, SightSeeing sightSeeing) {
      uiModel.addAttribute("sightSeeing", sightSeeing == null ? new SightSeeing() : sightSeeing);
  }
   
   void validate(CommonsMultipartFile commonsMultipartFile,Model uiModel, Errors errors) throws IOException{
      if (commonsMultipartFile.getSize() > 0){
         InputStream inputStream = commonsMultipartFile.getInputStream();
         if (!MimeTypeSupport.supportMineType(commonsMultipartFile.getContentType())){
            errors.reject("error_fileData_contenttype");
         }
         if (commonsMultipartFile.getSize() > FileInfoUtil.DEFAULT_BUFFER_SIZE){
            errors.reject("error_fileData_large");
         }
         if (!errors.hasFieldErrors("fileData")){
            Dimension dimension = SimpleImageInfo.processStream(inputStream);
            if (dimension.getWidth() < 200){
               errors.reject("error_fileData_limit_width");
            }
         }
      }
   }
}
